【CS61B】Lec16-Extends, Sets, Maps, and BSTs

  • ~2.67K 字
  1. 1. Lec16 - Extends, Sets, Maps, and BSTs
    1. 1.1. Extends
      1. 1.1.1. 例:实现RotatingSLList
      2. 1.1.2. 例:实现VengefulSLList
    2. 1.2. BST
      1. 1.2.1. 随机表
      2. 1.2.2. 二叉搜索树的原理
      3. 1.2.3. 寻找特定元素
      4. 1.2.4. 添加元素
      5. 1.2.5. 删除元素

Lec16 - Extends, Sets, Maps, and BSTs

Extends

从前,若一个类是接口的下位词,我们使用implements来书写方法的实现

但若想实现一个类是另一个类的下位词,我们需要使用extends

extends可以用于类与类、接口与接口之间

例:实现RotatingSLList

即让最后一个元素右旋到第一个元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package Lec16;

public class RotatingSLList<Item> extends SLList<Item> {
public void rotateRight(){
Item x = removeLast();
addFirst(x);
}
public static void main(String[] args){
RotatingSLList<Integer> rsl = new RotatingSLList<>();
rsl.addLast(10);
rsl.addLast(11);
rsl.addLast(12);
rsl.addLast(13);

rsl.rotateRight();
rsl.print();
}
}

extends继承了SLList中的所有成员:

  • 所有实例与静态变量
  • 所有方法(除了构造函数)
  • 所有嵌套类

但若成员是私有的就无法访问了

例:实现VengefulSLList

记录被删除的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package Lec16;


import java.util.ArrayList;
import java.util.List;

public class VengefulSLList<Item> extends SLList<Item>{
private SLList<Item> deletedItems ;
public VengefulSLList(){
deletedItems = new SLList<Item>();
}

@Override
public Item removeLast(){
Item removedItem = super.removeLast(); // 使用父类的方法
deletedItems.addLast(removedItem);
return removedItem;
}
public void printLostItems(){
deletedItems.print();
}
public static void main(String[] args){
VengefulSLList<Integer> vsl = new VengefulSLList<>();
vsl.addLast(1);
vsl.addLast(5);
vsl.addLast(10);
vsl.addLast(15);

vsl.removeLast();
vsl.removeLast();

vsl.printLostItems();
}
}

这里我们实现了对继承方法的重写

其中,我们可以使用super来调用父类中的方法

BST

随机表

链表的搜索效率较慢,我们可以在不同节点间随机额外添加一些链接,这样可以依赖随机性获得更好的效率

二叉搜索树的原理

若我们将每次搜索都折半,就能大幅提高效率,一个链表可以进行如下改造:

BST

这是一棵二叉搜索树

二叉搜索树是一个有根的二叉树,对于书中的每个节点

  • 左子树中的每个节点的值都小于该节点的值
  • 右子树中的每个节点的值都大于该节点的值
BST

寻找特定元素

  • 若待寻找元素等于当前元素,返回
  • 若待寻找元素小于当前元素,前往左子树寻找
  • 若待寻找元素大于当前元素,前往右子树寻找

时间复杂度:

因此搜索一颗完全BST的速度是很快的

1
2
3
4
5
6
7
8
9
10
static BST find(BST T, key sk){
if (T==null)
return null;
if (sk.equals(T.key))
return T;
else if (sk<T.key)
return find(T.left, sk);
else
return find(T.right, sk);
}

添加元素

首先寻找待插入元素

  • 若找到了就不进行操作
  • 若没找到
    • 创建一个新节点
    • 创建合适链接

使用递归书写

1
2
3
4
5
6
7
8
9
static BST insert(BST T, key ik){
if (T==null)
return new BST(ik);
if (ik<T.key)
T.left = insert(T.left, ik);
else if (ik>T.key)
T.right = insert(T.right, ik);
return T;
}

删除元素

删除没有孩子的节点:

直接删除,即将其父节点对应的左/右节点置空

删除一个孩子的节点:

要在维持BST性质的前提下删除:可以发现该节点的孩子一定大于(右侧)或小于(左侧)该节点

故我们可以寻找该节点的孩子,将指向它的节点指向他的孩子即可

删除两个孩子的节点:

找到左子树最大的节点或右子树最小的节点,替代待删除节点即可

赞助喵
非常感谢您的喜欢!
赞助喵